﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Chat.Client
{
    public abstract class ServerCmdEventArgs<Cmd> : CmdEventArgs<Cmd>
        where Cmd : Server.ServerCmd
    {
        public ServerCmdEventArgs(Cmd commandReceived) :
            base(commandReceived)
        {
        }
    }
    public abstract class LoginResponseEventArgs<Cmd> :
        ServerCmdEventArgs<Cmd> where Cmd : Server.LoginResponseCmd
    {
        public LoginResponseEventArgs(Cmd commandReceived)
            : base(commandReceived)
        {
        }
    }
    public class LoginOkEventArgs : LoginResponseEventArgs<Server.LoginOkCmd>
    {
        public LoginOkEventArgs(Server.LoginOkCmd commandReceived)
            : base(commandReceived)
        {
        }
    }
    public class LoginFailedEventArgs : LoginResponseEventArgs<Server.LoginFailedCmd>
    {
        public LoginFailedEventArgs(Server.LoginFailedCmd commandReceived)
            : base(commandReceived)
        {
        }
    }
    public class ReceiveMsgEventArgs : ServerCmdEventArgs<Server.ReceiveMsgCmd>
    {
        public ReceiveMsgEventArgs(Server.ReceiveMsgCmd commandReceived)
            : base(commandReceived)
        {
        }
    }
    public class UsersOnlineEventArgs : ServerCmdEventArgs<Server.UsersOnlineCmd>
    {
        public UsersOnlineEventArgs(Server.UsersOnlineCmd commandReceived)
            : base(commandReceived)
        {
        }
    }
    
    public class ServerCmdProcessor : CmdProcessor<Server.ServerCmd>
    {
        public event EventHandler<LoginOkEventArgs> LoggedIn;
        public event EventHandler<LoginFailedEventArgs> LoginFailed;
        public event EventHandler<ReceiveMsgEventArgs> MessageReceived;
        public event EventHandler<UsersOnlineEventArgs> UsersUpdate;

        public override void ProcessCommand(Chat.Server.ServerCmd baseCmd)
        {
            if (baseCmd is Server.LoginOkCmd)
                OnLoggedIn(new LoginOkEventArgs(baseCmd as Server.LoginOkCmd));
            else if (baseCmd is Server.LoginFailedCmd)
                OnLoginFailed(new LoginFailedEventArgs(baseCmd as Server.LoginFailedCmd));
            else if (baseCmd is Server.ReceiveMsgCmd)
                OnMessageReceived(new ReceiveMsgEventArgs(baseCmd as Server.ReceiveMsgCmd));
            else if (baseCmd is Server.UsersOnlineCmd)
                OnUsersUpdate(new UsersOnlineEventArgs(baseCmd as Server.UsersOnlineCmd));
            else
                throw new UnexpectedCmdException(baseCmd);
        }

        protected virtual void OnLoggedIn(LoginOkEventArgs e)
        {
            if (LoggedIn != null)
                LoggedIn(this, e);
        }
        protected virtual void OnLoginFailed(LoginFailedEventArgs e)
        {
            if (LoginFailed != null)
                LoginFailed(this, e);
        }
        protected virtual void OnMessageReceived(ReceiveMsgEventArgs e)
        {
            if (MessageReceived != null)
                MessageReceived(this, e);
        }
        protected virtual void OnUsersUpdate(UsersOnlineEventArgs e)
        {
            if (UsersUpdate != null)
                UsersUpdate(this, e);
        }
    }
}
